﻿using System;
using System.Net;
using Softelligent.Zintra.ClientSDK;
using Softelligent.Zintra.Synchronizations.ProductsAccessConsole.Properties;

namespace Softelligent.Zintra.Synchronizations.ProductsAccessConsole
{
    class Program
    {
        private const string HelpCommand = "/?";
        private const string StoreCommand = "/store";
        private const string SyncCommand = "/sync";
        private const string ActivateCommand = "/activate";
        private const string AllAction = "all";
        private const string SingleAction = "single";
        private static ConsoleManager consoleManager;

        /// <summary>
        /// Execute a sync command
        /// 
        /// Store the products in the local database command
        ///     store all
        /// Add a single product to the local database command
        ///     store single add [your data Id]
        /// Update a single product to the local database command
        ///     store single change [your data Id]
        /// Remove a single product to the local database command
        ///     store single remove [your data Id]
        /// Sync all changes command
        ///     sync
        /// </summary>
        /// <param name="args">arguments contain commands for the synchronisation</param>
        private static void Sync(string[] args)
        {
            if (args.Length < 1)
            {
                return;
            }

            var command = args[0];
            if (string.Compare(command, StoreCommand, true) == 0 && args.Length > 1)
            {
                var action = args[1];
                if (string.Compare(action, AllAction, true) == 0)
                {
                    Console.WriteLine("{0} Begin storing all", DateTime.UtcNow);
                    consoleManager.Store();
                    Console.WriteLine("{0} End storing all", DateTime.UtcNow);
                }
                else if (string.Compare(action, SingleAction, true) == 0 && args.Length > 3)
                {
                    Console.WriteLine("{0} Begin storing single", DateTime.UtcNow);
                    consoleManager.Store(args[2], args[3]);
                    Console.WriteLine("{0} End storing single", DateTime.UtcNow);
                }
            }
            else if (string.Compare(command, SyncCommand, true) == 0)
            {
                Console.WriteLine("{0} Begin syncing", DateTime.UtcNow);
                consoleManager.Sync();
                Console.WriteLine("{0} End syncing", DateTime.UtcNow);
            }
        }

        private static void Initialize()
        {
            Console.WriteLine("{0} Initialize", DateTime.UtcNow);

            if (!consoleManager.HasSubscription())
            {
                Console.WriteLine("You still need to activate your application.");
                Activate();
            }
        }

        private static void Activate()
        {
            var activationKey = GetActivationKey();
            try
            {
                var dto = Resource.Products.UsingJSON.Activate(Settings.Default.ProductId, activationKey);
                consoleManager.StoreSubscription(dto.Token);
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.UnknownError ||
                    ex.Status == WebExceptionStatus.ProtocolError)
                {
                    Console.WriteLine("Your activation key was incorrect.");
                    Console.WriteLine("Please try again.");
                    Console.WriteLine();
                    Activate();
                }
                else
                {
                    Console.WriteLine("There was a problem connecting. ({0})", ex.Status);
                    Console.WriteLine("Please try again later.");
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Press enter to quit.");
                    Console.ResetColor();
                    Console.ReadLine();
                    Environment.Exit(-1);
                }
            }
        }

        private static Guid GetActivationKey()
        {
            Console.WriteLine("Enter your activation key and press enter: ");
            var activationKey = Guid.Empty;
            while (activationKey == Guid.Empty)
            {
                Guid.TryParse(Console.ReadLine(), out activationKey);
            }
            return activationKey;
        }

        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Invalid arguments, use /? for help.");
                return;
            }
            if (args.Length == 1 && args[0] == HelpCommand)
            {
                Console.WriteLine("Synchronization with this console is a two step process.");
                Console.WriteLine("--------------------------------------------------------");
                Console.WriteLine("\t- First you need to store data from the datastore you want to synchronize.");
                Console.WriteLine("\t- Next you need to synchronize your data with Zintra.");
                Console.WriteLine();
                Console.WriteLine("Console arguments");
                Console.WriteLine("\t- Smart store all data");
                Console.WriteLine("\t\t Softelligent.Zintra.Sync.ClientConsole.exe /store all");
                Console.WriteLine("\t- Add a single item");
                Console.WriteLine("\t\t Softelligent.Zintra.Sync.ClientConsole.exe /store single add [id in the datastore]");
                Console.WriteLine("\t- Change a single item");
                Console.WriteLine("\t\t Softelligent.Zintra.Sync.ClientConsole.exe /store single change [id in the datastore]");
                Console.WriteLine("\t- Remove a single item");
                Console.WriteLine("\t\t Softelligent.Zintra.Sync.ClientConsole.exe /store single remove [id in the datastore]");
                Console.WriteLine();
                Console.WriteLine("\t- Synchronize all data");
                Console.WriteLine("\t\t Softelligent.Zintra.Sync.ClientConsole.exe /sync");
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("Force an activation.");
                Console.WriteLine("--------------------");
                Console.WriteLine("\t\t Softelligent.Zintra.Sync.ClientConsole.exe /activate");
                return;
            }

            consoleManager = new ConsoleManager();

            if (args.Length == 1 && args[0] == ActivateCommand)
            {
                Activate();
                return;
            }

            Console.WriteLine("{0} Begin configuring", DateTime.UtcNow);

            Initialize();

            Console.WriteLine("{0} End configuring", DateTime.UtcNow);

            Sync(args);

            Console.WriteLine("{0} Finished", DateTime.UtcNow);
        }
    }
}
